/*
database 包定义了数据库操作的基础接口和通用结构，
为不同类型数据库（如MySQL、Redis等）提供统一的操作规范，
便于上层代码对数据库进行抽象访问，降低对具体数据库实现的依赖。
*/
package database

import "errors" // 用于定义数据库操作相关的错误类型

// DBType 数据库类型的字符串别名，用于标识不同的数据库类型，
// 便于在配置和接口实现中统一区分数据库种类
type DBType string

// 数据库类型常量定义，涵盖常见数据库，确保类型标识的一致性，避免硬编码字符串
const (
	DBTypeMySQL    DBType = "mysql"    // 标识MySQL数据库
	DBTypeRedis           = "redis"    // 标识Redis数据库
	DBTypeMongoDB         = "mongodb"  // 标识MongoDB数据库
	DBTypePostgres DBType = "postgres" // 标识PostgreSQL数据库
)

// Config 数据库连接配置结构体，封装了连接数据库所需的所有参数，
// 用于初始化数据库连接时传递配置信息，支持不同类型数据库的通用配置
type Config struct {
	Type     DBType `json:"type"`     // 数据库类型，对应DBType常量（如"mysql"），用于指定要连接的数据库种类
	Host     string `json:"host"`     // 数据库服务器的IP地址或主机名（如"localhost"、"192.168.1.1"）
	Port     int    `json:"port"`     // 数据库服务监听的端口号（如MySQL默认3306，Redis默认6379）
	Username string `json:"username"` // 连接数据库的用户名，用于身份验证
	Password string `json:"password"` // 连接数据库的密码，用于身份验证
	Database string `json:"database"` // 要连接的数据库名称（部分数据库如Redis可能不使用此参数）
	PoolSize int    `json:"poolSize"` // 数据库连接池大小，控制并发连接数量，避免频繁创建连接
	Timeout  int    `json:"timeout"`  // 连接超时时间（单位通常为秒），超过此时长则连接失败
}

// NewConfig 创建一个默认的数据库配置实例，
// 提供常用的默认值，简化配置初始化过程，用户可在此基础上修改特定参数
// 返回值：
//
//	*Config: 初始化后的默认配置实例
func NewConfig() *Config {
	return &Config{
		Type:     DBTypeMySQL,      // 默认数据库类型为MySQL
		Host:     "localhost",      // 默认主机为本地
		Port:     3306,             // 默认端口为MySQL的3306
		Username: "root",           // 默认用户名为root
		Password: "",               // 默认密码为空
		Database: "game_server_db", // 默认数据库名为game_server_db
		PoolSize: 10,               // 默认连接池大小为10
		Timeout:  30,               // 默认超时时间为30秒
	}
}

// Database 数据库操作基础接口，定义了所有数据库实现必须支持的核心方法，
// 统一数据库操作的入口，使上层代码可通过接口访问不同数据库而无需修改逻辑
type Database interface {
	// Connect 建立与数据库的连接，根据配置信息初始化连接（如连接池、认证等）
	//
	// 返回值：
	//   error: 连接成功返回nil，失败返回具体错误信息（如网络问题、认证失败）
	Connect() error

	// Disconnect 断开与数据库的连接，释放连接资源（如关闭连接池）
	//
	// 返回值：
	//   error: 断开成功返回nil，失败返回具体错误信息
	Disconnect() error

	// Ping 检查与数据库的连接是否有效，通常用于心跳检测或连接有效性验证
	//
	// 返回值：
	//   error: 连接有效返回nil，无效返回错误信息（如连接已断开）
	Ping() error

	// Type 返回当前数据库的类型，对应DBType常量，用于区分不同数据库实现
	//
	// 返回值：
	//   DBType: 数据库类型标识（如DBTypeMySQL）
	Type() DBType

	// GetConfig 获取当前数据库的连接配置，便于查看或修改配置信息
	//
	// 返回值：
	//   *Config: 数据库连接配置的指针
	GetConfig() *Config
}

// BaseDatabase 数据库接口的基础实现结构体，封装了通用的配置存储功能，
//
// 作为其他具体数据库实现（如MySQL、Redis）的嵌入结构体，避免重复实现配置相关方法
type BaseDatabase struct {
	config *Config // 数据库连接配置，存储当前数据库的连接参数，由构造函数传入
}

// NewBaseDatabase 创建基础数据库实例，初始化配置信息
//
// 参数：
//
//	config: 数据库连接配置指针，包含连接所需的所有参数
//
// 返回值：
//
//	*BaseDatabase: 初始化后的基础数据库实例
func NewBaseDatabase(config *Config) *BaseDatabase {
	return &BaseDatabase{
		config: config, // 存储传入的配置信息，供后续获取配置使用
	}
}

// GetConfig 实现Database接口的GetConfig方法，返回当前数据库的连接配置
//
// 返回值：
//
//	*Config: 存储在BaseDatabase中的配置指针
func (db *BaseDatabase) GetConfig() *Config {
	return db.config
}

// 数据库操作相关的错误变量定义，统一错误类型，便于上层代码判断错误原因
var (
	ErrDBNotConnected    = errors.New("database not connected")    // 数据库未连接时的错误（如调用操作前未执行Connect）
	ErrDBOperationFailed = errors.New("database operation failed") // 数据库操作执行失败时的错误（如查询、插入失败）
	ErrRecordNotFound    = errors.New("record not found")          // 未找到目标记录时的错误（如查询结果为空）
)
